package ar.edu.itba.pod.legajo45129;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.PropertyConfigurator;

import ar.edu.itba.pod.legajo45129.simul.communication.ConnectionManagerImpl;
import ar.edu.itba.pod.legajo45129.statistics.GetStatistics;
import ar.edu.itba.pod.simul.ObjectFactoryAlternative;
import ar.edu.itba.pod.simul.market.Market;
import ar.edu.itba.pod.simul.market.MarketManager;
import ar.edu.itba.pod.simul.market.Resource;
import ar.edu.itba.pod.simul.simulation.Agent;
import ar.edu.itba.pod.simul.simulation.SimulationManager;
import ar.edu.itba.pod.simul.time.TimeMapper;
import ar.edu.itba.pod.simul.time.TimeMappers;
import ar.edu.itba.pod.simul.ui.ConsoleFeedbackCallback;
import ar.edu.itba.pod.simul.ui.FeedbackCallback;
import ar.edu.itba.pod.simul.ui.FeedbackMarketManager;
import ar.edu.itba.pod.simul.ui.FeedbackSimulationManager;
import ar.edu.itba.pod.simul.units.Factory;
import ar.edu.itba.pod.simul.units.SimpleConsumer;
import ar.edu.itba.pod.simul.units.SimpleProducer;



public class SingleNode {
	
	public static void main(String[] args) {
		PropertyConfigurator.configure("config/log4j.properties");
		FeedbackCallback callback = new ConsoleFeedbackCallback();
		TimeMapper timeMapper = TimeMappers.oneSecondEach(6, TimeUnit.HOURS);
		
		ObjectFactoryAlternative ofa = new MyObjectFactoryAlternative("localhost", timeMapper);
		
		MarketManager marketManager = ofa.getMarketManager();
		marketManager = new FeedbackMarketManager(callback, marketManager);

		marketManager.start();
		Market market = marketManager.market();
		
		SimulationManager sim = ofa.getSimulationManager();
		sim = new FeedbackSimulationManager(callback, sim);
		sim.register(Market.class, market);
		
		// define simulation agents
		Resource pigIron = new Resource("Mineral", "Pig Iron");
		Resource copper = new Resource("Mineral", "Copper");
		Resource steel = new Resource("Alloy", "Steel");
		Resource diamond = new Resource("Mineral", "Diamond");
		Resource gold = new Resource("Mineral", "Gold");
		
		// create the agents
		Agent mine1 = SimpleProducer.named("pig iron mine")
									.producing(2).of(pigIron)
									.every(12, TimeUnit.HOURS)
									.build();
		Agent mine2 = SimpleProducer.named("copper mine")
									.producing(4).of(copper)
									.every(1, TimeUnit.DAYS)
									.build();
		Agent mine3 = SimpleProducer.named("diamond mine")
									.producing(1).of(diamond)
									.every(6, TimeUnit.DAYS).
									build();
		Agent mine4 = SimpleProducer.named("gold mine")
									.producing(6).of(gold).
									every(6, TimeUnit.HOURS).
									build();
		Agent refinery = Factory.named("steel refinery")
									.using(8, pigIron)
									.and(2,copper)
									.and(1, diamond)
									.producing(6, steel)
									.every(40, TimeUnit.DAYS)
									.build();
		Agent factory = SimpleConsumer.named("factory")
									.consuming(8).of(steel)
									.consuming(10).of(gold)
									.every(40, TimeUnit.DAYS)
									.build();
		
		// put the agents in a queue
		ConcurrentLinkedQueue<Agent> agentsQueue = new ConcurrentLinkedQueue<Agent>();
		agentsQueue.add(mine1);
		agentsQueue.add(mine2);
		agentsQueue.add(mine3);
		agentsQueue.add(mine4);
		agentsQueue.add(refinery);
		agentsQueue.add(factory);
		
		long numberOfAgents = 0;
		
		
		
		while(true){
			// retrieve it from the top of the queue
			Agent aux = agentsQueue.remove();
			
			// add agent to the simulation
			ofa.getSimulationManager().addAgent(aux);
			
			System.out.println("Number of running agents: " + ++numberOfAgents);
			
			// put it in the tail
			agentsQueue.add(aux);

			Thread thread = new Thread(new GetStatistics((ConnectionManagerImpl) ofa.getConnectionManager()));
			thread.start();
			
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	
	
}
